
#import "GameManager.h"

int W=320;
int H=480;

@implementation GameManager

#pragma mark ============================= Init Methods ===============================

+ (GameManager*) getInstance  {
    
    static GameManager* gameManager;
		
	if (!gameManager) {
        gameManager = [[GameManager alloc] init];
		[gameManager preloader];            
	}
	    
    return gameManager;
}

- (void) preloader {
    sprites = [[NSMutableArray alloc] initWithCapacity:20];
    newSprites = [[NSMutableArray alloc] initWithCapacity:20];
    destroyableSprites = [[NSMutableArray alloc] initWithCapacity:20];
    
    background = [self getPic: @"background.png"];    
    state = LOAD_GAME;
}

- (void) loadGame { 
    [sprites removeAllObjects];
    [newSprites removeAllObjects];
    [destroyableSprites removeAllObjects];   
    
    NSString *schillerQoute = @"Und die Sonne Homers, siehe! sie lächelt auch uns."; 
    NSString *schillerKey = @"schillerKey";
    [self saveObject: schillerQoute key: schillerKey];
    
    NSString *result = [self readObjectforKey: schillerKey];
    if (result) {
        NSLog(@"Storage output: %@", result);
    }
    
    NSDate* date = [NSDate date];    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];  
    [dateFormatter setDateStyle: NSDateFormatterShortStyle];
    [dateFormatter setTimeStyle: NSDateFormatterLongStyle];
    NSString *dateString = [dateFormatter stringFromDate: date];
        
    NSString *highscoresKey = @"highscoresKey";      
    NSMutableDictionary *highscores = [self readObjectforKey: highscoresKey];
    if (!highscores) {
        highscores = [[NSMutableDictionary alloc] initWithCapacity: 10];
    }     

    NSArray *keys = [highscores keysSortedByValueUsingSelector: @selector(compare:)];
    NSNumber *score = [NSNumber numberWithInt: 0];
    for (id key in keys) {
        score = [highscores objectForKey: key];
        NSLog(@"Date: %@, Score: %@", key, score);
    }
    
    int newScore = [self getRndBetween: 1 and: 9999];
    if (newScore > [score intValue]) {
        NSLog(@"NEW HIGHSCORE: %i!", newScore);                
        NSNumber *scoreObj = [NSNumber numberWithInt: newScore];
        [highscores setObject: scoreObj forKey: dateString];
        [self saveObject: highscores key: highscoresKey]; 
    } else {
        NSLog(@"Score: %i. Sorry no new highscore.", newScore);
    }
    
    //Cleanup
    [dateFormatter release];
}

- (void) createSprite: (int) type 
                speed: (CGPoint) sxy 
                  pos: (CGPoint) pxy {      
}

#pragma mark ============================= Game Handler ===============================

- (void) touchBegan: (CGPoint) p {}
- (void) touchMoved: (CGPoint) p {}
- (void) touchEnded {}

- (void) drawStatesWithFrame: (CGRect) frame { 
    W = frame.size.width;
    H = frame.size.height;     
    switch (state) {
        case LOAD_GAME: 
            [self loadGame];
            state = PLAY_GAME;         
            break; 
        case PLAY_GAME:            
            [self playGame];
            break;          
        default: NSLog(@"ERROR: Unkown state: %i", state);
            break;
    }    
}	 

- (void) playGame {   
    [background drawAtPoint: CGPointMake(0, 0)];
    [self drawString: @"Persistance (see console logs)" at: CGPointMake(5, 5)];
    [self manageSprites];             
    [self renderSprites];     
} 

- (void) checkSprite: (Sprite *) sprite {}

#pragma mark ============================= Helper Methods ===============================

- (void) setState: (int) stt {
    state = stt;
}

- (void) manageSprites {
    //NSLog(@"Sprites: %i destroyable: %i new: %i", [sprites count], [destroyableSprites count], [newSprites count]);
    
    //Cleanup 
    for (Sprite *destroyableSprite in destroyableSprites) { 
        for (Sprite *sprite in sprites) { 
            if (destroyableSprite == sprite) { 
                [sprites removeObject: sprite];
                break;
            }
        }   
    }  
    
    for (Sprite *newSprite in newSprites){ 
        [sprites addObject: newSprite];   
    } 
    
    [destroyableSprites removeAllObjects]; 
    [newSprites removeAllObjects];
}

- (void) renderSprites {
    for (Sprite *sprite in sprites) { 
        if ([sprite isActive]) {             
            [self checkSprite: sprite];
            [sprite draw]; 
        } else {
            [destroyableSprites addObject: sprite]; 
        }    
    } 
}

- (NSMutableDictionary *) getDictionary {
	if (!dictionary) { //Hashtable
		dictionary = [[NSMutableDictionary alloc] init]; 
	}
	return dictionary;
}

- (UIImage *) getPic: (NSString*) picName {
	@try { 
		UIImage *pic = [[self getDictionary] objectForKey: picName];
		if (!pic) {
			pic = [UIImage imageNamed: picName]; 
			[[self getDictionary] setObject: pic forKey: picName];
            int memory = pic.size.width*pic.size.height*4;
			NSLog(@"%@ stored, Size: %i KB", picName, memory/1024);
            [pic release]; 
		}          
		return pic;
	} 
	@catch (id theException) {
		NSLog(@"ERROR: %@ not found!", picName);		
	} 
	return nil;
}

- (AVAudioPlayer *) getSound: (NSString *) soundName {	
    @try {				
		AVAudioPlayer *sound = [[self getDictionary] objectForKey: soundName];		
        if (!sound) {			
            NSError *error;
            NSString *path = [[NSBundle mainBundle] pathForResource: soundName ofType: nil];             
			sound = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL fileURLWithPath: path] 
                                                           error: &error];             
            if (!sound) {
                NSLog(@"ERROR: Wrong sound format: %@. Description: %@", 
                      soundName, 
                      [error localizedDescription]);
            } else {
                sound.volume = 0.7;
                int len = sound.duration;
                [[self getDictionary] setObject: sound forKey: soundName];
                NSLog(@"%@ loaded, duration: %i sec", soundName, len);
                [sound release];
            }    
		} 
        return sound;
	} 
	@catch (id theException) {
        NSLog(@"ERROR: %@ not found!", soundName);
	} 
    return nil;
}

- (void) playSound: (NSString *) soundName {
    AVAudioPlayer *sound = [self getSound: soundName];
	if (sound) {   
        sound.currentTime = 0;        
        if (!sound.playing) {
            sound.numberOfLoops = 0;
            [sound play];
        }    
    } 
}

- (void) loopSound: (NSString *) soundName {
    AVAudioPlayer *sound = [self getSound: soundName];
	if (sound) {
        if (!sound.playing) {
            sound.currentTime = 0;
            sound.numberOfLoops = -1;
            [sound play]; 
        }
    } 
}

- (void) stopSound: (NSString *) soundName {
    AVAudioPlayer *sound = [self getSound: soundName];
	if (sound && sound.playing) {			
        [sound stop];         
    } 
}

- (void) saveObject: (id) object key: (NSString *) key {
    NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
    [storage setObject: object forKey: key];
}

- (id) readObjectforKey: (NSString *) key {
    NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];    
    return [storage objectForKey: key];
}

- (int) getRndBetween: (int) bottom and: (int) top {		
	int rnd = bottom + (arc4random() % (top+1-bottom)); 
	return rnd;
} 

- (void) drawString: (NSString *) str at: (CGPoint) p {
    UIFont *uif = [UIFont fontWithName: @"Verdana-Italic" size: 20];
	CGContextSetRGBFillColor(UIGraphicsGetCurrentContext(), 0, 0, 0, 1);
    [str drawAtPoint: p withFont: uif]; 
} 

- (void) dealloc {        
    [sprites release];
    [newSprites release];
    [destroyableSprites release];
    [dictionary release];
    [super dealloc];
}

@end
